#include "CGaugeSemiCircle.h"
#include "ui_CGaugeSemiCircle.h"

CGaugeSemiCircle::CGaugeSemiCircle(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CGaugeSemiCircle)
{
    ui->setupUi(this);

    //this->setGeometry(0, 0, this->geometry().width(), this->geometry().height());
                  /*     float(this->size().width() / 400) * this->geometry().width(),
                       float(this->size().width() / 300) * this->geometry().height());
                       */
    //this->setStyleSheet("border-image:url(/quguan/picture/transparent.png)");

    qDebug() << this->geometry();
    setRange(0, 50);
    setValue(5);
    setPrecision(1);

    setScaleMajor(5);
    setScaleMinor(10);

    setStartAngle(90);
    setEndAngle(90);


    setOuterCircleColor(QColor(112, 113, 0));
    setInnerCircleColor(QColor(112, 113, 111));

    setPieColorStart(QColor(112, 0, 111));
    setPieColorMid(QColor(0, 113, 111));
    setPieColorEnd(QColor(112, 113, 0));

    //setScaleColor(QColor(207, 171, 105));
    setScaleColor(QColor(Qt::white)); // 刻度尺寸的颜色
    setTextColor(QColor(255, 0, 255));

    setPointerColor(QColor(112, 113, 0));

    m_value = 25.4;
    qDebug() << getStartAngle() << ": " << getEndAngle();

}

CGaugeSemiCircle::~CGaugeSemiCircle()
{
    delete ui;
}

void CGaugeSemiCircle::paintEvent(QPaintEvent *)
{
    //qDebug() << "draw1";
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);

    painter.scale(side / 200.0, side / 200.0);

    //绘制外圆
    drawOuterCircle(&painter);
    /**/
    //绘制内圆
    //drawInnerCircle(&painter);
    //绘制饼圆
    //drawColorPie(&painter);
    //绘制覆盖圆 用以遮住饼圆多余部分
    //drawCoverCircle(&painter);
    //绘制刻度线
    drawScale(&painter);
    //绘制刻度值
    drawScaleNum(&painter);

    //根据指示器形状绘制指示器
    /*
    if (pointerStyle == PointerStyle_Circle) {
        drawPointerCircle(&painter);
    } else if (pointerStyle == PointerStyle_Indicator) {
        drawPointerIndicator(&painter);
    } else if (pointerStyle == PointerStyle_IndicatorR) {
        drawPointerIndicatorR(&painter);
    } else if (pointerStyle == PointerStyle_Triangle) {
        drawPointerTriangle(&painter);
    }
    */

    //绘制指针中心圆外边框
    //drawRoundCircle(&painter);
    //绘制指针中心圆
    //drawCenterCircle(&painter);
    //绘制当前值
    drawValue(&painter);
    //绘制遮罩层
    //drawOverlay(&painter);
    /**/
    //qDebug() << "draw2";
}

void CGaugeSemiCircle::drawOuterCircle(QPainter *painter)
{
    int radius = 40;
    painter->save();
    //painter->setPen(Qt::NoPen);
    painter->setPen(QPen(Qt::white, 3, Qt::SolidLine));
    //painter->setBrush(outerCircleColor);
    //painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->drawArc(-radius, -radius, radius * 2, radius * 2, 0*16, 180*16);
    //painter->drawArc(0, 0, radius * 2, radius * 2, 0*16, 180*16);
    painter->restore();
}

void CGaugeSemiCircle::drawInnerCircle(QPainter *painter)
{
    int radius = 90;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(innerCircleColor);
    //painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->drawPie(-radius, -radius, radius * 2, radius * 2, 0*16, 180*16);
    painter->restore();
}

void CGaugeSemiCircle::drawColorPie(QPainter *painter)
{
    int radius = 60;
    painter->save();
    painter->setPen(Qt::NoPen);

    QRectF rect(-radius, -radius, radius * 2, radius * 2);

    if (pieStyle == PieStyle_Three) {
        //计算总范围角度,根据占比例自动计算三色圆环范围角度
        //可以更改比例
        double angleAll = 360.0 - startAngle - endAngle;
        double angleStart = angleAll * 0.7;
        double angleMid = angleAll * 0.15;
        double angleEnd = angleAll * 0.15;

        //增加偏移量使得看起来没有脱节
        int offset = 3;

        //绘制开始饼圆
        painter->setBrush(pieColorStart);
        //painter->drawPie(rect, (270 - startAngle - angleStart) * 16, angleStart * 16);
        painter->drawPie(rect, 0 * 16, 180 * 16);

        //绘制中间饼圆
        painter->setBrush(pieColorMid);
        //painter->drawPie(rect, (270 - startAngle - angleStart - angleMid) * 16 + offset, angleMid * 16);
        painter->drawPie(rect, 0 * 16, 180 * 16);

        //绘制结束饼圆
        painter->setBrush(pieColorEnd);
        //painter->drawPie(rect, (270 - startAngle - angleStart - angleMid - angleEnd) * 16 + offset * 2, angleEnd * 16);
        painter->drawPie(rect, 0 * 16, 180 * 16);
    }
    else if (pieStyle == PieStyle_Current) {
        //计算总范围角度,当前值范围角度,剩余值范围角度
        double angleAll = 360.0 - startAngle - endAngle;
        double angleCurrent = angleAll * ((m_value - minValue) / (maxValue - minValue));
        double angleOther = angleAll - angleCurrent;

        //绘制当前值饼圆
        painter->setBrush(pieColorStart);
        painter->drawPie(rect, (270 - startAngle - angleCurrent) * 16, angleCurrent * 16);

        //绘制剩余值饼圆
        painter->setBrush(pieColorEnd);
        painter->drawPie(rect, (270 - startAngle - angleCurrent - angleOther) * 16, angleOther * 16);
    }

    painter->restore();
}

void CGaugeSemiCircle::drawCoverCircle(QPainter *painter)
{
    int radius = 50;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(coverCircleColor);
    //painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->drawPie(-radius, -radius, radius * 2, radius * 2, 0*16, 180*16);
    painter->restore();
}

void CGaugeSemiCircle::drawScale(QPainter *painter)
{
    int radius = 58; //72;
    painter->save();

    //painter->rotate(startAngle);
    painter->rotate(90);
    int steps = (scaleMajor * scaleMinor);
    double angleStep = (180.0 ) / steps;

    QPen pen;
    pen.setColor(scaleColor);
    pen.setCapStyle(Qt::RoundCap);

    for (int i = 0; i <= steps; i++)
    {
        if(i < m_value)
        {
            pen.setWidthF(0.8);
            //pen.setColor(Qt::blue);
            pen.setColor(QColor(207, 171, 105));
        }
        else
        {
            pen.setWidthF(0.5);
            pen.setColor(Qt::white);
        }

        painter->setPen(pen);
        painter->drawLine(0, radius - 10, 0, radius); // 刻度线的长度

        painter->rotate(angleStep);
    }

    painter->restore();
}

void CGaugeSemiCircle::drawScaleNum(QPainter *painter)
{
    int radius = 58;
    painter->save();
    painter->setPen(scaleColor);

    double startRad = (360 - startAngle - 90) * (M_PI / 180);
    double deltaRad = (360 - startAngle - endAngle) * (M_PI / 180) / scaleMajor;

    for (int i = 0; i <= scaleMajor; i++)
    {
        if(i > 0 && i < scaleMajor)
        {
            continue;
        }
        double sina = qSin(startRad - i * deltaRad);
        double cosa = qCos(startRad - i * deltaRad);
        double value = 1.0 * i * ((maxValue - minValue) / scaleMajor) + minValue;

        QString strValue = QString("%1").arg(value); //.arg((double)value, 0, 'f', precision);
        double textWidth = fontMetrics().width(strValue);
        double textHeight = fontMetrics().height();
        int x = radius * cosa - textWidth / 2;
        int y = -radius * sina + textHeight * 0.8;

        if(i == 0)
        {
            x -= textWidth *0; //1.5;
        }
        else
        {
            x += textWidth *0;
        }
        QFont font;
        font.setPixelSize(radius/5);
        painter->setFont(font);

        painter->drawText(x, y, strValue);
    }

    painter->restore();
}

void CGaugeSemiCircle::drawPointerCircle(QPainter *painter)
{
    int radius = 6;
    int offset = 30;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(pointerColor);

    painter->rotate(startAngle);
    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (m_value - minValue);
    painter->rotate(degRotate);
    //painter->drawEllipse(-radius, radius + offset, radius * 2, radius * 2);
    painter->drawPie(-radius, radius + offset, radius * 2, radius * 2, 0*16, 180*16);
    painter->restore();
}

void CGaugeSemiCircle::drawPointerIndicator(QPainter *painter)
{
    int radius = 75;
    painter->save();
    painter->setOpacity(0.8);
    painter->setPen(Qt::NoPen);
    painter->setBrush(pointerColor);

    QPolygon pts;
    pts.setPoints(3, -5, 0, 5, 0, 0, radius);

    painter->rotate(startAngle);
    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (m_value - minValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    painter->restore();
}

void CGaugeSemiCircle::drawPointerIndicatorR(QPainter *painter)
{
    int radius = 75;
    painter->save();
    painter->setOpacity(1.0);

    QPen pen;
    pen.setWidth(1);
    pen.setColor(pointerColor);
    painter->setPen(pen);
    painter->setBrush(pointerColor);

    QPolygon pts;
    pts.setPoints(3, -5, 0, 5, 0, 0, radius);

    painter->rotate(startAngle);
    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (m_value - minValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    //增加绘制圆角直线,与之前三角形重叠,形成圆角指针
    pen.setCapStyle(Qt::RoundCap);
    pen.setWidthF(4);
    painter->setPen(pen);
    painter->drawLine(0, 0, 0, radius);

    painter->restore();
}

void CGaugeSemiCircle::drawPointerTriangle(QPainter *painter)
{
    int radius = 10;
    int offset = 38;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(pointerColor);

    QPolygon pts;
    pts.setPoints(3, -5, 0 + offset, 5, 0 + offset, 0, radius + offset);

    painter->rotate(startAngle);
    double degRotate = (360.0 - startAngle - endAngle) / (maxValue - minValue) * (m_value - minValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    painter->restore();
}

void CGaugeSemiCircle::drawRoundCircle(QPainter *painter)
{
    int radius = 18;
    painter->save();
    painter->setOpacity(0.8);
    painter->setPen(Qt::NoPen);
    painter->setBrush(pointerColor);
    //painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->drawPie(-radius, -radius, radius * 2, radius * 2, 0*16, 180*16);
    painter->restore();
}

void CGaugeSemiCircle::drawCenterCircle(QPainter *painter)
{
    int radius = 15;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(centerCircleColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void CGaugeSemiCircle::drawValue(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(textColor);

    QFont font;
    font.setPixelSize(20);
    painter->setFont(font);

    // 温度
    /*
    font.setPixelSize(18);
    painter->setFont(font);
    QRectF textRect0(-radius*0.85, -radius*0.85, radius * 2, radius * 1.0);
    QString strValue0 = QString("温度");
    painter->drawText(textRect0, Qt::AlignLeft, strValue0);
    */

    // 单位
    font.setPixelSize(13);
    painter->setFont(font);
    QRectF textRect1(-radius, -radius*0.9, radius * 2, radius * 1.3);
    QString strValue1 = QString("℃");
    painter->drawText(textRect1, Qt::AlignCenter, strValue1);
    // 数值
    font.setPixelSize(23);
    painter->setFont(font);
    QRectF textRect(-radius, -radius, radius * 2, radius * 2.0);
    QString strValue;
    if(m_value <= maxValue && m_value >= minValue)
    {
        strValue = QString("%1").arg((double)m_value, 0, 'f', precision);
    }
    else
    {
        strValue = QString("--");
    }
    painter->drawText(textRect, Qt::AlignCenter, strValue);


    painter->restore();
}

void CGaugeSemiCircle::drawOverlay(QPainter *painter)
{
    if (!showOverlay) {
        return;
    }

    int radius = 90;
    painter->save();
    painter->setPen(Qt::NoPen);

    QPainterPath smallCircle;
    QPainterPath bigCircle;
    radius -= 1;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius *= 2;
    bigCircle.addEllipse(-radius, -radius + 140, radius * 2, radius * 2);

    //高光的形状为小圆扣掉大圆的部分
    QPainterPath highlight = smallCircle - bigCircle;

    QLinearGradient linearGradient(0, -radius / 2, 0, 0);
    overlayColor.setAlpha(100);
    linearGradient.setColorAt(0.0, overlayColor);
    overlayColor.setAlpha(30);
    linearGradient.setColorAt(1.0, overlayColor);
    painter->setBrush(linearGradient);
    painter->rotate(-20);
    painter->drawPath(highlight);

    painter->restore();
}

double CGaugeSemiCircle::getMinValue() const
{
    return this->minValue;
}

double CGaugeSemiCircle::getMaxValue() const
{
    return this->maxValue;
}

double CGaugeSemiCircle::getValue() const
{
    return this->m_value;
}

int CGaugeSemiCircle::getPrecision() const
{
    return  this->precision;
}

int CGaugeSemiCircle::getScaleMajor() const
{
    return this->scaleMajor;
}

int CGaugeSemiCircle::getScaleMinor() const
{
    return this->scaleMinor;
}

int CGaugeSemiCircle::getStartAngle() const
{
    return this->startAngle;
}

int CGaugeSemiCircle::getEndAngle() const
{
    return this->endAngle;
}

bool CGaugeSemiCircle::getAnimation() const
{
    return this->animation;
}

double CGaugeSemiCircle::getAnimationStep() const
{
    return this->animationStep;
}

QColor CGaugeSemiCircle::getOuterCircleColor() const
{
    return this->outerCircleColor;
}

QColor CGaugeSemiCircle::getInnerCircleColor() const
{
    return this->innerCircleColor;
}

QColor CGaugeSemiCircle::getPieColorStart() const
{
    return this->pieColorStart;
}

QColor CGaugeSemiCircle::getPieColorMid() const
{
    return this->pieColorMid;
}

QColor CGaugeSemiCircle::getPieColorEnd() const
{
    return this->pieColorEnd;
}

QColor CGaugeSemiCircle::getCoverCircleColor() const
{
    return this->coverCircleColor;
}

QColor CGaugeSemiCircle::getScaleColor() const
{
    return this->scaleColor;
}

QColor CGaugeSemiCircle::getPointerColor() const
{
    return this->pointerColor;
}

QColor CGaugeSemiCircle::getCenterCircleColor() const
{
    return this->centerCircleColor;
}

QColor CGaugeSemiCircle::getTextColor() const
{
    return this->textColor;
}

bool CGaugeSemiCircle::getShowOverlay() const
{
    return this->showOverlay;
}

QColor CGaugeSemiCircle::getOverlayColor() const
{
    return this->overlayColor;
}

CGaugeSemiCircle::PieStyle CGaugeSemiCircle::getPieStyle() const
{
    return this->pieStyle;
}

CGaugeSemiCircle::PointerStyle CGaugeSemiCircle::getPointerStyle() const
{
    return this->pointerStyle;
}

QSize CGaugeSemiCircle::sizeHint() const
{
    return QSize(50, 50); // ***********
}

QSize CGaugeSemiCircle::minimumSizeHint() const
{
    return QSize(10, 10); // ***********
}

void CGaugeSemiCircle::setRange(double minValue, double maxValue)
{
    if(this->minValue != minValue)
    {
        this->minValue = minValue;
    }
    if(this->maxValue != maxValue)
    {
        this->maxValue = maxValue;
    }
    this->update();
}

void CGaugeSemiCircle::setRange(int minValue, int maxValue)
{
    if(this->minValue != minValue)
    {
        this->minValue = minValue;
    }
    if(this->maxValue != maxValue)
    {
        this->maxValue = maxValue;
    }
    this->update();
}

void CGaugeSemiCircle::setMinValue(double value)
{
    if(this->minValue != value)
    {
        this->minValue = value;
        this->update();
    }
}

void CGaugeSemiCircle::setMaxValue(double value)
{
    if(this->maxValue != value)
    {
        this->maxValue = value;
        this->update();
    }
}

void CGaugeSemiCircle::setValue(double value)
{
    qDebug() << "this->value: " << this->m_value;
    if(this->m_value != value)
    {
        this->m_value = value;
        this->update();
    }
}

void CGaugeSemiCircle::setValue(int value)
{
    if(this->m_value != value)
    {
        this->m_value = value;
        this->update();
    }
}

void CGaugeSemiCircle::setPrecision(int precision)
{
    if(this->precision != precision)
    {
        this->precision = precision;
        this->update();
    }
}

void CGaugeSemiCircle::setScaleMajor(int scaleMajor)
{
    if(this->scaleMajor != scaleMajor)
    {
        this->scaleMajor = scaleMajor;
        this->update();
    }
}

void CGaugeSemiCircle::setScaleMinor(int scaleMinor)
{
    if(this->scaleMinor != scaleMinor)
    {
        this->scaleMinor = scaleMinor;
        this->update();
    }
}

void CGaugeSemiCircle::setStartAngle(int startAngle)
{
    if(this->startAngle != startAngle)
    {
        this->startAngle = startAngle;
        this->update();
    }
}

void CGaugeSemiCircle::setEndAngle(int endAngle)
{
    if(this->endAngle != endAngle)
    {
        this->endAngle = endAngle;
        this->update();
    }
}

void CGaugeSemiCircle::setAnimation(bool animation)
{
    if(this->animation != animation)
    {
        this->animation = animation;
        this->update();
    }
}

void CGaugeSemiCircle::setAnimationStep(double animationStep)
{
    if(this->animationStep != animationStep)
    {
        this->animationStep = animationStep;
        this->update();
    }
}

void CGaugeSemiCircle::setOuterCircleColor(const QColor &outerCircleColor)
{
    if(this->outerCircleColor != outerCircleColor)
    {
        this->outerCircleColor = outerCircleColor;
        this->update();
    }
}

void CGaugeSemiCircle::setInnerCircleColor(const QColor &innerCircleColor)
{
    if(this->innerCircleColor != innerCircleColor)
    {
        this->innerCircleColor = innerCircleColor;
        this->update();
    }
}

void CGaugeSemiCircle::setPieColorStart(const QColor &pieColorStart)
{
    if(this->pieColorStart != pieColorStart)
    {
        this->pieColorStart = pieColorStart;
        this->update();
    }
}

void CGaugeSemiCircle::setPieColorMid(const QColor &pieColorMid)
{
    if(this->pieColorMid != pieColorMid)
    {
        this->pieColorMid = pieColorMid;
        this->update();
    }
}

void CGaugeSemiCircle::setPieColorEnd(const QColor &pieColorEnd)
{
    if(this->pieColorEnd != pieColorEnd)
    {
        this->pieColorEnd = pieColorEnd;
        this->update();
    }
}

void CGaugeSemiCircle::setCoverCircleColor(const QColor &coverCircleColor)
{
    if(this->coverCircleColor != coverCircleColor)
    {
        this->coverCircleColor = coverCircleColor;
        this->update();
    }
}

void CGaugeSemiCircle::setScaleColor(const QColor &scaleColor)
{
    if(this->scaleColor != scaleColor)
    {
        this->scaleColor = scaleColor;
        this->update();
    }
}

void CGaugeSemiCircle::setPointerColor(const QColor &pointerColor)
{
    if(this->pointerColor != pointerColor)
    {
        this->pointerColor = pointerColor;
        this->update();
    }
}

void CGaugeSemiCircle::setCenterCircleColor(const QColor &centerCircleColor)
{
    if(this->centerCircleColor != centerCircleColor)
    {
        this->centerCircleColor = centerCircleColor;
        this->update();
    }
}

void CGaugeSemiCircle::setTextColor(const QColor &textColor)
{
    if(this->textColor != textColor)
    {
        this->textColor = textColor;
        this->update();
    }
}

void CGaugeSemiCircle::setShowOverlay(bool showOverlay)
{
    if(this->showOverlay != showOverlay)
    {
        this->showOverlay = showOverlay;
        this->update();
    }
}

void CGaugeSemiCircle::setOverlayColor(const QColor &overlayColor)
{
    if(this->overlayColor != overlayColor)
    {
        this->overlayColor = overlayColor;
        this->update();
    }
}

void CGaugeSemiCircle::setPieStyle(const CGaugeSemiCircle::PieStyle &pieStyle)
{
    if(this->pieStyle != pieStyle)
    {
        this->pieStyle = pieStyle;
        this->update();
    }
}

void CGaugeSemiCircle::setPointerStyle(const CGaugeSemiCircle::PointerStyle &pointerStyle)
{
    if(this->pointerStyle != pointerStyle)
    {
        this->pointerStyle = pointerStyle;
        this->update();
    }
}

/*
bool CGaugeSemiCircle::eventFilter(QObject *watched, QEvent *event)
{
    static QPoint point;
    static QPoint point2;
    if(watched == ui->centralWidget )
    {
        switch (event->type())
        {
            case QEvent::MouseButtonPress:
                qDebug() << cursor().pos();
                break;
            case QEvent::MouseButtonRelease:
            {
                qDebug() << cursor().pos();
            }
                break;

            default:
                break;
        }
    }
    return QWidget::eventFilter(watched,event);//将事件传递给父类
}
*/
